import re

from django import http
from django.conf import settings
from django.contrib.auth import login
from django.shortcuts import render, redirect

# Create your views here.
from django.urls import reverse
from django.views import View
from django_redis import get_redis_connection

from apps.ausers.models import User
from apps.oauth.models import OAuthQQUser
from meiduo_mall.settings.dev import logger
from utils.response_code import RETCODE


# 判断是否绑定了openid
from utils.secret import SecretOauth


def is_bind_openid(openid, request):
    try:
        oauth_user = OAuthQQUser.objects.get(openid=openid)
    except Exception as e:
        logger.error(e)
        # 2.未绑定了   ---跳转到 绑定的页面
        #加密openid
        data_dict = {'openid': openid}
        secret_openid = SecretOauth.dumps(data_dict)
        context = {'openid': secret_openid}
        return render(request, 'oauth_callback.html', context)
    else:
        # 1.绑定 --保持登录状态---设置username--cookie--跳转到首页
        user = oauth_user.user
        #   保持登录状态
        login(request, user)
        #   ---设置username--cookie
        if next:
            response = redirect(next)
        else:
            response = redirect(reverse('contents:index'))
        # --跳转到首页
        response.set_cookie('username', user.username, max_age=3600 * 24 * 14)

        return response


# QQ 登录--code-->token-->openid
# http://www.meiduo.site:8000/oauth_callback?code=514D2BE5E31DBC30106501CDC03ACD0A&state=None


class QQAuthUserView(View):
    def get(self, request):

        code = request.GET.get('code')
        next = request.GET.get('state')
        if not code:
            return http.HttpResponseForbidden('缺少code')

        from QQLoginTool.QQtool import OAuthQQ
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI,
                        state=next)

        try:
            # code-->token
            access_token = oauth.get_access_token(code)
            # token--->openid
            openid = oauth.get_open_id(access_token)
        except Exception as e:
            logger.error(e)
            return http.HttpResponseServerError('Oauth2.0认证失败!')

        # 判断是否绑定了openid
        response = is_bind_openid(openid, request,next)
        # 返回前端
        return response


        # 1.获取登录url

    def post(self, request):
        # 1.接收参数
        mobile = request.POST.get('mobile')
        pwd = request.POST.get('password')
        sms_code_client = request.POST.get('sms_code')
        openid = request.POST.get('openid')
        # 2.解析参数
        # 判断参数是否齐全
        if not all([mobile, pwd, sms_code_client]):
            return http.HttpResponseForbidden('缺少必传参数')
        # 判断手机号是否合法
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.HttpResponseForbidden('请输入正确的手机号码')
        # 判断密码是否合格
        if not re.match(r'^[0-9A-Za-z]{8,20}$', pwd):
            return http.HttpResponseForbidden('请输入8-20位的密码')
        # 3.校验短信 redis取出来
        # 判断短信验证码是否一致
        redis_conn = get_redis_connection('verify_code')
        sms_code_server = redis_conn.get('sms_%s' % mobile)
        if sms_code_server is None:
            return render(request, 'oauth_callback.html', {'sms_code_errmsg': '无效的短信验证码'})
        if sms_code_client != sms_code_server.decode():
            return render(request, 'oauth_callback.html', {'sms_code_errmsg': '输入短信验证码有误'})

        #openid 校验
            # 解密出openid 再判断openid是否有效

        openid = SecretOauth().loads(openid).get('openid')
        if not openid:
            return render(request, 'oauth_callback.html', {'openid_errmsg': '无效的openid'})
        # 4.判断用户是否存在 mobile=mobile
        try:
             User.objects.get(mobile=mobile)
        except Exception as e:
            logger.error(e)
            #不存在新建了
            user = User.objects.create_user(username=mobile, password=pwd, mobile=mobile)
        else:
            # 如果用户存在，检查用户密码
            if not User.check_password(pwd):
                return render(request, 'oauth_callback.html', {'account_errmsg': '用户名或密码错误'})
        # 5.openid和user绑定 ==新建一条记录
        try:
           OAuthQQUser.objects.create(openid=openid,
                                    user=user
                                    )
        except Exception as e:
            logger.error(e)
            return render(request, 'oauth_callback.html', {'qq_login_errmsg': 'QQ登录失败'})
        # 6.login（）-set_cookie 重定向到首页
        login(request, user)
        next = request.GET.get('state')
        if next:
            response = redirect(next)
        else:
             response = redirect(reverse('contents:index'))

        response.set_cookie('username', user.username, max_age=3600 * 24 * 15)

        return response


class QQAuthURLView(View):
    def get(self, request):
        # 1.实例化 qq认证类
        next = request.GET.get('next')
        from QQLoginTool.QQtool import OAuthQQ
        oauth_qq = OAuthQQ(
            client_secret=settings.QQ_CLIENT_SECRET,
            client_id=settings.QQ_CLIENT_ID,
            redirect_uri=settings.QQ_REDIRECT_URI,
            state = next,
        )

        # 2.获取登录网址
        login_url = oauth_qq.get_qq_url()

        # 3.返回给前端
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'login_url': login_url})
